<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>msc_transcoder_test with three.js</title>
    <link rel="shortcut icon" href="../ktx_favicon.ico" type="image/x-icon" />
  </head>
  <script src="../msc_basis_transcoder.js"></script>
  <!--
  <script defer src="https://unpkg.com/es-module-shims@0.4.6/dist/es-module-shims.js"></script>
  -->
  <!-- Use an import map shim to ensure KTX2Loader and the demo itself
       use the same CDN-hosted copy of the threejs library. -->
  <!--
  <script type="importmap-shim">
  {
    "imports": {
      "https://raw.githack.com/donmccurdy/three.js/feat-ktx2loader/build/three.module.js": "https://unpkg.com/three@0.114.0/build/three.module.js"
    }
  }
  </script>
  -->
  <style>
    html, body { width:100%; height:100%; margin:0; padding:0; }
    canvas { display:block; }
    h2 { margin-top: 0; }
    #panel {
      position: absolute;
      color: white;
      background-color:rgba(0.3, 0.3, 0.3, 0.3);
      padding: 0.5em;
      left: 50%;
      transform: translate(-50%, 0);
      max-width: 50em;
    }
  </style>
  <div id="panel">
    <h2>msc_basis_transcoder test</h2>
    <p>
      Loads and parses KTX2 files with a plain JS loader, transcodes the
      Basis Universal payload with <code>msc_basis_transcoder</code>,
      and renders the result with three.js. The first KTX2 file contains
      BasisLZ/ETC1S format and the second UASTC format. These textures
      have been transcoded to <b id='format'>FORMAT</b>.
    </p>
    <div id="log"></div>
  </div>
  <!-- <script type="module-shim"> -->
  <script type="module">
    import * as THREE from 'https://unpkg.com/three@0.114.0/build/three.module.js';
    import { OrbitControls } from 'https://unpkg.com/three@0.114.0/examples/jsm/controls/OrbitControls.js';
    /*
    import { KTX2Loader } from 'https://raw.githack.com/donmccurdy/three.js/feat-ktx2loader/examples/jsm/loaders/KTX2Loader.js';
    */
    import { KTX2Loader } from '/llt-three/KTX2Loader.js';

    const width = window.innerWidth;
    const height = window.innerHeight;

    const renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( width, height );
    renderer.outputEncoding = THREE.sRGBEncoding;
    document.body.appendChild( renderer.domElement );

    const scene = new THREE.Scene();
    scene.background = new THREE.Color( 0xF0F0F0 );

    const camera = new THREE.PerspectiveCamera( 60, width / height, 0.1, 100 );
    camera.position.set( 2, 1.5, 1 );
    camera.lookAt( scene.position );
    scene.add(camera);

    const controls = new OrbitControls( camera, renderer.domElement );
    controls.autoRotate = true;

    // FIXME: compressed textures don't support? KTX2 compressed textures do.
    // PlaneBufferGeometry UVs assume flipY=true, which compressed textures don't support.
    const geometry = flipY( new THREE.PlaneBufferGeometry() );
    const materialEtc1s = new THREE.MeshBasicMaterial( {
      color: 0xFFFFFF,
      side: THREE.DoubleSide,
      defines: {DECAL: ""}
    } );
    /* This isn't working. No time for further investigation.
    const myShader = [
        'diffuseColor *= texelColor;',
        '#ifndef DECAL',
        '    diffuseColor *= texelColor;',
        '#else',
        '    diffuseColor = vec4( mix( diffuse, texelColor.rgb, texelColor.a ), opacity );',
        '#endif',
    ].join( '\n' );
    materialEtc1s.onBeforeCompile = function ( shader ) {
        shader.fragmentShader = shader.fragmentShader.replace(
            myShader
        );
    };
    */

    const materialUastc = new THREE.MeshBasicMaterial( {
      alphaTest: 1.0,
      color: 0xFFFFFF,
      side: THREE.DoubleSide
    } );
    var meshEtc1s = new THREE.Mesh(geometry, materialEtc1s);
    meshEtc1s.position.z = -0.5;

    var meshUastc = new THREE.Mesh(geometry, materialUastc);
    meshUastc.position.z = +0.5;

    scene.add(meshEtc1s, meshUastc);

    const formats = [
      'RGBA_ASTC_4x4_Format',
      'RGB_S3TC_DXT1_Format',
      'RGBA_S3TC_DXT5_Format',
      'RGB_PVRTC_4BPPV1_Format',
      'RGBA_PVRTC_4BPPV1_Format',
      'RGB_ETC1_Format',
      'RGB_ETC2_Format',
      'RGBA_ETC2_EAC_Format',
    ];

    const formatToString = ( format ) => formats.find( ( name ) => THREE[ name ] === format );

    animate();

    var loader = new KTX2Loader().detectSupport( renderer )

    loader.load( '../libktx-webgl/ktx_app_basis.ktx2', ( texture ) => {

        materialEtc1s.map = texture;
        elem('format').innerText = formatToString( materialEtc1s.map.format );

        materialEtc1s.needsUpdate = true;

      }, ( p ) => console.log( `...${p}` ), ( e ) => console.error( e ) );

    loader.load( '../libktx-webgl/ktx_document_uastc_rdo5.ktx2', ( texture ) => {

        materialUastc.map = texture;
        //elem('format').innerText = formatToString( materialEtc1s.map.format );

        materialUastc.needsUpdate = true;

      }, ( p ) => console.log( `...${p}` ), ( e ) => console.error( e ) );

    function elem(id) {
      return document.getElementById(id);
    }

    function animate() {

      requestAnimationFrame( animate );

      meshUastc.needsUpdate = true;
      controls.update();

      renderer.render( scene, camera );

    }

    window.addEventListener( 'resize', () => {

      const width = window.innerWidth;
      const height = window.innerHeight;

      camera.aspect = width / height;
      camera.updateProjectionMatrix();
      renderer.setSize( width, height );

    }, false );

    // FIXME: read the orientation metadata and only do this if it indicates
    // Y orientation is up.
    /** Correct UVs to be compatible with `flipY=false` textures. */
    function flipY ( geometry ) {

      var uv = geometry.attributes.uv;

      for ( var i = 0; i < uv.count; i ++ ) {

        uv.setY( i, 1 - uv.getY( i ) );

      }

      return geometry;

    }
  </script>
</html>
